require("hwOutMsg")
require("tool")
require("misc")
require("lbsLoc")

module(..., package.seeall)

local lng_value = "0"
local lat_value = "0"
local beat = 0
local function devNotInList(list, dev_name)
    for i, v in ipairs(list) do
        if list[i].device_id == dev_name then
            return false
        end
    end

    return true
end

-- 获取网关的经纬度
local function getLocCb(result, lat, lng, addr, time, locType)
    log.info("testLbsLoc.getLocCb", result, lat, lng)
    -- 获取经纬度成功
    if result == 0 then
        -- log.info("服务器返回的时间", time:toHex())
        -- log.info("定位类型，基站定位成功返回0", locType)
        lat_value = tostring(lat)
        lng_value = tostring(lng)
        return true
        -- 失败
    else
        return false
    end
end

-- 设备初次启动
local function onceStart()
    if hwIotda.isReady() then
        sys.taskInit(function()
            ril.regUrc("+NITZ", function()
                log.info("cell.timeSync")
                bTimeSyned = true
            end)

            sys.wait(1000)
            lbsLoc.request(getLocCb)
            -- local t = misc.getClock()
            -- misc.getTemperature(getTemperatureCb)

            local clk = os.date("*t", os.time()) -- 获取UTC时间的table
            local timeStr = string.format("%02d-%02d-%02d %02d:%02d:%02d",
                    clk.year, clk.month, clk.day,
                    clk.hour, clk.min, clk.sec) -- 时间戳
            log.info("HW time", timeStr)

            sys.wait(1000)

            -- local num, on_num = ui_index.returnOnlineNum()
            local re = {}
            re["services"] = { {} }
            re["services"][1]["service_id"] = "base"
            re["services"][1]["properties"] = {}
            if lat_value ~= "0" or lng_value ~= "0" then
                re["services"][1]["properties"]["lat"] = tonumber(lat_value)
                re["services"][1]["properties"]["lon"] = tonumber(lng_value)
            end
            re["services"][1]["properties"]["fwVersion"] = _G.VERSION
            re["services"][1]["properties"]["supplier"] = "LINKTA"
            re["services"][1]["properties"]["model"] = "LTG-03"
            re["services"][1]["properties"]["iccid"] = tostring(sim.getIccid())
            re["services"][1]["properties"]["rssi"] = net.getRssi()
            re["services"][1]["properties"]["reportTime"] = timeStr
            re["services"][1]["properties"]["pass"] = nvm.get("PASSWORD")

            hwOutMsg.hwInstertMsg("$oc/devices/" .. config.HW_DEV_PRODUCTID ..
                    "_GWEV_" .. misc.getImei() ..
                    "/sys/properties/report", re)
            -- mqttOutMsg.mqttInsertMsg(config.MQTT_TOPIC2, re)
        end)
    end
end

-- 求平均值
local function getAvg(data_list)
    local avg = "-999"

    if #data_list > 0 then
        local res = tool.Split(data_list, ",")
        local avg_count = 0
        local avg_sum = 0
        for i, v in ipairs(res) do
            if tonumber(v) > 0 then
                avg_count = avg_count + 1
                avg_sum = avg_sum + tonumber(v)
            end
        end
        avg = tostring(avg_sum / avg_count)
    end

    return avg

end

-- 发送环境数据
function dataPostEnv(data_list)
    if hwIotda.isReady() then
        beat = tool.miscTime()
        sys.taskInit(function()
            local temp_avg = "-999"
            local hum_avg = "-999"
            if #data_list.temp_buf > 0 then
                data_list.temp_buf = string.sub(data_list.temp_buf, 1, -2)
                temp_avg = getAvg(data_list.temp_buf)
            end
            if #data_list.hum_buf > 0 then
                data_list.hum_buf = string.sub(data_list.hum_buf, 1, -2)
                hum_avg = getAvg(data_list.hum_buf)
            end

            if #data_list.co2_buf > 0 then
                data_list.co2_buf = string.sub(data_list.co2_buf, 1, -2)
            end

            local temp_name = ""
            local hum_name = ""
            local co2_name = ""
            local nh3_name = ""

            local type_list = tool.deepCopy(nvm.get("DEV_SUB_TYPE"))
            local add_list = tool.deepCopy(nvm.get("DEV_SUB_ADDR"))

            if #type_list > 0 then
                for i, v in ipairs(type_list) do
                    if tool.Split(v, "|")[2] == "TH" then
                        temp_name = temp_name .. tonumber(add_list[i], 16) .. ","
                        hum_name = hum_name .. tonumber(add_list[i], 16) .. ","
                    end

                    if tool.Split(v, "|")[2] == "CO2" then
                        co2_name = co2_name .. tonumber(add_list[i], 16) .. ","
                    end

                    if tool.Split(v, "|")[2] == "NH3" then
                        nh3_name = nh3_name .. tonumber(add_list[i], 16) .. ","
                    end
                end

                if #temp_name > 0 then
                    temp_name = string.sub(temp_name, 1, -2)
                end

                if #hum_name > 0 then
                    hum_name = string.sub(hum_name, 1, -2)
                end

                if #co2_name > 0 then
                    co2_name = string.sub(co2_name, 1, -2)
                end

                if #nh3_name > 0 then
                    nh3_name = string.sub(nh3_name, 1, -2)
                end
            end

            local re = {}
            re["devices"] = {}
            re["devices"][1] = {}
            re["devices"][1]["device_id"] = config.HW_ENV_PRODUCT_KEY .. "_" .. string.sub(misc.getImei(), -6, -1) ..
                    "_ENV"
            re["devices"][1]["services"] = { {} }
            re["devices"][1]["services"][1]["service_id"] = "sensor"
            re["devices"][1]["services"][1]["properties"] = {}

            if data_list.temp_buf ~= nil and #data_list.temp_buf > 0 then
                re["devices"][1]["services"][1]["properties"]["tempList"] = tool.SplitNum(data_list.temp_buf, ",")
                re["devices"][1]["services"][1]["properties"]["tempNameList"] = tool.Split(temp_name, ",")
                re["devices"][1]["services"][1]["properties"]["inAvgTemp"] = temp_avg
            end

            if data_list.hum_buf ~= nil and #data_list.hum_buf > 0 then
                re["devices"][1]["services"][1]["properties"]["humiList"] = tool.SplitNum(data_list.hum_buf, ",")
                re["devices"][1]["services"][1]["properties"]["humiNameList"] = tool.Split(hum_name, ",")
                re["devices"][1]["services"][1]["properties"]["inAvgHumi"] = hum_avg
            end

            if data_list.co2_buf ~= nil and #data_list.co2_buf > 0 then
                re["devices"][1]["services"][1]["properties"]["avgCo2"] = tool.SplitNum(data_list.co2_buf, ",")
                re["devices"][1]["services"][1]["properties"]["co2NameList"] = tool.Split(co2_name, ",")
            end

            if data_list.nh3_buf ~= nil and #data_list.nh3_buf > 0 then
                re["devices"][1]["services"][1]["properties"]["avgAmmo"] = tool.SplitNum(data_list.nh3_buf, ",")
                re["devices"][1]["services"][1]["properties"]["ammoNameList"] = tool.Split(nh3_name, ",")
            end

            if data_list.out_temp ~= nil and #data_list.out_temp > 0 then
                re["devices"][1]["services"][1]["properties"]["outAvgTemp"] = data_list.out_temp
            end

            if data_list.out_hum ~= nil and #data_list.out_hum > 0 then
                re["devices"][1]["services"][1]["properties"]["outAvgHumi"] = data_list.out_hum
            end

            if data_list.state ~= nil and #data_list.state > 0 and data_list.cur_buf ~= nil and #data_list.cur_buf > 0 then
                log.info("FAN_SATE")
                table.insert(re["devices"][1]["services"], {})
                re["devices"][1]["services"][2]["service_id"] = "device"
                re["devices"][1]["services"][2]["properties"] = {}
                re["devices"][1]["services"][2]["properties"]["fanStateList"] = tool.SplitNum(data_list.state, ",")
                re["devices"][1]["services"][2]["properties"]["fanCurrentList"] = tool.SplitNum(data_list.cur_buf, ",")
            end

            hwOutMsg.hwInstertMsg(
                    "$oc/devices/" .. config.HW_DEV_PRODUCTID .. "_GWEV_" ..
                            misc.getImei() ..
                            "/sys/gateway/sub_devices/properties/report", re)
        end)
    end
end

function dataPostElc(data)
    if hwIotda.isReady() then
        beat = tool.miscTime()
        sys.taskInit(function()
            local re = {}
            re["devices"] = {}
            re["devices"][1] = {}
            re["devices"][1]["device_id"] = config.HW_ELECT_PRODUCT_KEY .. "_" .. string.sub(misc.getImei(), -6, -1) ..
                    "_ELC"
            re["devices"][1]["services"] = { {} }
            re["devices"][1]["services"][1]["service_id"] = "sensor"
            re["devices"][1]["services"][1]["properties"] = {}
            re["devices"][1]["services"][1]["properties"]["value"] = data

            if #re["devices"] > 0 then
                hwOutMsg.hwInstertMsg(
                        "$oc/devices/" .. config.HW_DEV_PRODUCTID .. "_GWEV_" ..
                                misc.getImei() ..
                                "/sys/gateway/sub_devices/properties/report", re)
            end
        end)
    end
end

-- 子设备上线
function subsetLogin(key, id)
    log.info("HW LOGIN", id)

    local data = {}
    data["services"] = { {} }
    data["services"][1]["service_id"] = "$sub_device_manager"
    data["services"][1]["event_type"] = "sub_device_update_status"
    data["services"][1]["paras"] = {}
    data["services"][1]["paras"]["device_statuses"] = {}

    local temp = {}
    temp["device_id"] = key .. "_" .. id
    temp["status"] = "ONLINE"
    table.insert(data["services"][1]["paras"]["device_statuses"], temp)

    hwOutMsg.hwInstertMsg(
            "$oc/devices/" .. config.HW_DEV_PRODUCTID .. "_GWEV_" .. misc.getImei() ..
                    "/sys/events/up", data)
end

-- 子设备下线
function subsetLogout(key, id)
    log.info("HW LOGOut", id)

    local data = {}
    data["services"] = { {} }
    data["services"][1]["service_id"] = "$sub_device_manager"
    data["services"][1]["event_type"] = "sub_device_update_status"
    data["services"][1]["paras"] = {}
    data["services"][1]["paras"]["device_statuses"] = {}

    local temp = {}
    temp["device_id"] = key .. "_" .. id
    temp["status"] = "OFFLINE"
    table.insert(data["services"][1]["paras"]["device_statuses"], temp)

    hwOutMsg.hwInstertMsg(
            "$oc/devices/" .. config.HW_DEV_PRODUCTID .. "_GWEV_" .. misc.getImei() ..
                    "/sys/events/up", data)
end

-- 更新拓扑关系
function updateTopo()
    local topic = "$oc/devices/" .. config.HW_DEV_PRODUCTID .. "_GWEV_" ..
            misc.getImei() .. "/sys/events/up"
    local re = {}
    re["services"] = { {} }
    re["services"][1]["service_id"] = "$sub_device_manager"
    re["services"][1]["event_type"] = "sub_device_sync_request"
    re["services"][1]["paras"] = {}
    -- re["services"][1]["paras"]["version"] = 1
    hwOutMsg.hwInstertMsg(topic, re)
    log.info("HW UPDATE TOPO")
end

-- 新增子设备
function subDevAdd(id, key)
    local data = {}
    data["services"] = { {} }
    data["services"][1]["service_id"] = "$sub_device_manager"
    data["services"][1]["event_type"] = "add_sub_device_request"
    data["services"][1]["paras"] = {}
    data["services"][1]["paras"]["devices"] = { {} }
    data["services"][1]["paras"]["devices"][1]["name"] = id
    data["services"][1]["paras"]["devices"][1]["node_id"] = id
    data["services"][1]["paras"]["devices"][1]["product_id"] = key

    hwOutMsg.hwInstertMsg(
            "$oc/devices/" .. config.HW_DEV_PRODUCTID .. "_GWEV_" .. misc.getImei() ..
                    "/sys/events/up", data)
end

-- 删除子设备
function subDevDelet(id)
    local data = {}
    data["services"] = { {} }
    data["services"][1]["service_id"] = "$sub_device_manager"
    data["services"][1]["event_type"] = "delete_sub_device_request"
    data["services"][1]["paras"] = {}
    data["services"][1]["paras"]["devices"] = { {} }
    data["services"][1]["paras"]["devices"][1] = id

    hwOutMsg.hwInstertMsg(
            "$oc/devices/" .. config.HW_DEV_PRODUCTID .. "_GWEV_" .. misc.getImei() ..
                    "/sys/events/up", data)
end

function hwAlarm(id, name, detail, state)
    if hwIotda.isReady() then
        local clk = os.date("*t", os.time()) -- 获取UTC时间的table
        local timeStr = string.format("%02d%02d%02dT%02d%02d%02dZ",
                clk.year, clk.month, clk.day,
                clk.hour, clk.min, clk.sec) -- 时间戳

        local re = {}
        re["object_device_id"] = id
        re["services"] = { {} }
        re["services"][1]["service_id"] = "$alarm"
        re["services"][1]["event_type"] = "device_alarm"
        re["services"][1]["event_time"] = timeStr
        re["services"][1]["paras"] = {}
        re["services"][1]["paras"]["name"] = name
        re["services"][1]["paras"]["level"] = 0
        re["services"][1]["paras"]["status"] = state
        re["services"][1]["paras"]["detail"] = detail
        if state == 0 then
            re["services"][1]["paras"]["active_reason"] = detail
        elseif state == 1 then
            re["services"][1]["paras"]["recovery_reason"] = detail
        end

        hwOutMsg.hwInstertMsg(
                "$oc/devices/" .. config.HW_DEV_PRODUCTID .. "_GWEV_" .. misc.getImei() ..
                        "/sys/events/up", re)
    end
end

-- 设置风机相关参数
local function setFan(setType, jsonValue, resultId)
    local nvmName = ""

    if setType == "setRate" then
        nvmName = "FAN_RATE"
    elseif setType == "setOverCur" then
        nvmName = "FAN_OVER_CUR"
    elseif setType == "setUnderCur" then
        nvmName = "FAN_UNDER_CUR"
    end

    if nvmName ~= "" then
        local temp = tool.deepCopy(nvm.get(nvmName))
        local value = jsonValue

        local is_new = 1
        if #temp > 0 then
            for i, v in ipairs(temp) do
                -- 地址匹配
                if tool.Split(v, "|")[1] == tool.Split(value, "|")[1] then
                    temp[i] = value
                    is_new = 0
                end
            end
        else
            table.insert(temp, value)
        end

        if is_new == 1 then
            table.insert(temp, value)
        end

        nvm.set(nvmName, temp)
        local re = { ["result_code"] = 0, ["paras"] = {} }
        hwOutMsg.hwInstertMsg("$oc/devices/" ..
                config.HW_DEV_PRODUCTID ..
                "_GWEV_" .. misc.getImei() ..
                "/sys/commands/response/" ..
                resultId, re)
    end
end

-- 处理华为云命令
function hwCMD(topic, payload)
    sys.taskInit(function()
        local res = tool.Split(topic, "/")
        local json_data, json_result, errinfo = json.decode(payload)
        if #res == 6 and res[5] == "commands" and json_data["command_name"] == "param" and json_result == true then
            -- 重启命令
            if json_data["paras"]["cmd"] == "REBOOT" then
                local re = { ["result_code"] = 0, ["paras"] = {} }
                hwOutMsg.hwInstertMsg("$oc/devices/" ..
                        config.HW_DEV_PRODUCTID ..
                        "_GWEV_" .. misc.getImei() ..
                        "/sys/commands/response/" ..
                        res[6], re)
                sys.wait(2000)
                sys.restart("HW CMD REBOOT")
                --    发送指定的485数据
            elseif json_data["command_name"] == "CMD_HEX" then
                deviceConfig.hwMqttSend(json_data["paras"]["data"], topic)
                --    设置风机感应电流
            elseif json_data["paras"]["cmd"] == "setIndCur" then
                local value = json_data["paras"]["value"]
                nvm.set("FAN_IND_CUR", tonumber(value))
                local re = { ["result_code"] = 0, ["paras"] = {} }
                hwOutMsg.hwInstertMsg("$oc/devices/" ..
                        config.HW_DEV_PRODUCTID ..
                        "_GWEV_" .. misc.getImei() ..
                        "/sys/commands/response/" ..
                        res[6], re)
                --    设置风机倍率
            elseif json_data["paras"]["cmd"] == "setRate" then
                setFan("setRate", json_data["paras"]["value"], res[6])
                --    设置风机欠流电流
            elseif json_data["paras"]["cmd"] == "setUnderCur" then
                setFan("setUnderCur", json_data["paras"]["value"], res[6])
                --    设置风机过流电流
            elseif json_data["paras"]["cmd"] == "setOverCur" then
                setFan("setOverCur", json_data["paras"]["value"], res[6])
            end
        end
    end)
end

-- 启动定时上传心跳包任务
sys.taskInit(function()
    local result, data = sys.waitUntil("HW_MQTT_READY", 300000)
    if result then
        sys.wait(6000)
        onceStart()
        while true do
            sys.wait(300000)
            if tool.miscTime() - beat > 300 then
                onceStart()
            end
        end
    end
end)
